#include "types.h"
#include "help.h"
#include "test.h"
#include "sql.h"

extern sqlite3 * db;
extern void init();
extern std::vector <user> Subjects;
extern std::vector <file> Objects;
extern std::vector <SOA> ACM;
current_user cu;

int interface_get_subjects_num()
{
    return Subjects.size();
}
const char * interface_get_subjects_name(int i)
{
    return Subjects[i].name.c_str();
}
const char * interface_get_subjects_passwd(int i)
{
    return Subjects[i].password.c_str();
}
int interface_get_objects_num()
{
    return Objects.size();
}
const char * interface_get_objects_filename(int i)
{
    return Objects[i].filename.c_str();
}
const char * interface_get_objects_creator(int i)
{
    return Objects[i].creator.c_str();
}
const char * interface_get_objects_content(int i)
{
    return Objects[i].content.c_str();
}
int interface_get_right_num()
{
    return ACM.size();
}
const char * interface_get_right_username(int i)
{
    return ACM[i].user.c_str();
}
const char * interface_get_right_filename(int i)
{
    return ACM[i].filename.c_str();
}
const char * interface_get_right_from(int i)
{
    return ACM[i].from_to.c_str();
}

int interface_get_right_access(int i)
{
    return ACM[i].access;
}


int interface_login(char * username, char * passwd, int level, int flag)
{
    user u;
    u.name = std::string(username);
    u.password = std::string(passwd);
    cu = current_user(level, flag, u);
    sql_connect(db);
    init();
    if (verify(u))
    {
        if (level == 0)
        {
            if(strcmp(username, "admin") || strcmp(passwd, "root")) // root
            {
                return 0;
            }
        }
        return 1;
    }
    else
    {
        return 0;
    }
}

int interface_add_user(char * username, char * passwd)
{
    std::string s1, s2;
    s1 = std::string(username);
    s2 = std::string(passwd);
    return (cu.create_subject(s1, s2));
}
int interface_delete_user(char * username)
{
    std::string s1, s2;
    s1 = std::string(username);
    return (cu.delete_subject(s1));
}
int interface_add_file(char * filename, char * content)
{
    std::string s1, s2;
    s1 = std::string(filename);
    s2 = std::string(content);
    return cu.create_object(s1, s2);
}
int interface_delete_file(char * filename)
{
    std::string s1, s2;
    s1 = std::string(filename);
    return cu.delete_object(s1);
}
const char * interface_get_current_user()
{
    return cu.get_username().c_str();
}
int interface_transfer_right(char * username, char * filename, char * right)
{
    #define NAME_TO_ACCESS(a) names[a]
    std::string names [] = {"NULL", "READ", "WRITE", "NULL", "OWN"};
    int r = 0;
    if (!strcmp(right, "READ")) {
        r = 1;
    }
    else if (!strcmp(right, "WRITE")) {
        r = 2;
    }
    else if (!strcmp(right, "OWN")) {
        r = 4;
    }
    else {
        return 0;
    }
    std::string s1, s2;
    s1 = std::string(username);
    s2 = std::string(filename);   
    return cu.transfer_right(r, s1, s2);
}
int interface_revoke_right(char * username, char * filename, char * right)
{
    #define NAME_TO_ACCESS(a) names[a]
    std::string names [] = {"NULL", "READ", "WRITE", "NULL", "OWN"};
    int r = 0;
    if (!strcmp(right, "READ")) {
        r = 1;
    }
    else if (!strcmp(right, "WRITE")) {
        r = 2;
    }
    else if (!strcmp(right, "OWN")) {
        r = 4;
    }
    else {
        return 0;
    }
    std::string s1, s2;
    s1 = std::string(username);
    s2 = std::string(filename);
    return cu.revoke_right(r, s1, s2);
}
int interface_test()
{
    int level = 0;  // root(0) or normal(1)
    int flag = 0;   // central(0) or distributed(1)
    user u = {"admin", "root"}; 
    class current_user cu(level, flag, u);
    sqlite3_open("dac.db", &db);
    int nrow, ncol;
    char ** results, * errmsg = 0;
    sqlite3_get_table(db, "SELECT * FROM SUBJECTS", &results, &nrow, &ncol, &errmsg);
    init();
    test_central();
    return 1;
}